package com.nineclock.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.filter.CurrentUserHolder;
import com.nineclock.common.oss.OssClientUtils;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.SysCompanyDTO;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.mapper.SysCompanayMapper;
import com.nineclock.system.mapper.SysCompanayUserMapper;
import com.nineclock.system.mapper.SysCompanyUserRoleMapper;
import com.nineclock.system.mapper.SysRoleMapper;
import com.nineclock.system.pojo.SysCompany;
import com.nineclock.system.pojo.SysCompanyUser;
import com.nineclock.system.pojo.SysCompanyUserRole;
import com.nineclock.system.pojo.SysRole;
import com.nineclock.system.service.SysCompanyService;
import com.nineclock.system.service.SysCompanyUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@Service
@Transactional
public class SysCompanyServiceImpl implements SysCompanyService {

    @Autowired
    private SysCompanayMapper sysCompanayMapper;

    @Autowired
    private OssClientUtils ossClientUtils;

    @Autowired
    private SysCompanayUserMapper companayUserMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysCompanyUserRoleMapper companyUserRoleMapper;

    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    private SysCompanyUserService companyUserService;



    @Override
    public List<SysCompanyDTO> queryUserJoinCompany(Long userId) {
        // 参数校验
        if (userId == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        List<SysCompany> sysCompanyList=sysCompanayMapper.queryUserJoinCompany(userId);

        if (CollectionUtils.isEmpty(sysCompanyList)) {
            // 如果为空，代表未加入企业，抛出异常
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);

        }

        List<SysCompanyDTO> companyDTOList = BeanHelper.copyWithCollection(sysCompanyList, SysCompanyDTO.class);
        return companyDTOList;
    }

    @Override
    public SysCompanyDTO queryCompanyInfo() {
        // 获取当前登录用户id
        Long companyId = CurrentUserHolder.get().getCompanyId();

        // 根据id查询企业信息
        SysCompany sysCompany = sysCompanayMapper.selectById(companyId);

        if (sysCompany == null){
            //报错误：企业不存在
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        return BeanHelper.copyProperties(sysCompany,SysCompanyDTO.class);
    }


    //企业管理: 上传图片
    @Override
    public String uploadCompanyLogo(MultipartFile file) throws Exception{
        // 参数校验
        if(file == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        // 文件类型校验
        String contentType = file.getContentType();
        if(!NcConstant.ALLOWED_IMG_TYPES.contains(contentType)){
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }

        // 文件大小校验
        if(file.getSize() > NcConstant.maxFileSize){
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }

        // 调用阿里云oss工具类上传文件
        String fileUrl = ossClientUtils.uploadFile(file.getOriginalFilename(), file.getInputStream());

        return fileUrl;
    }

//    企业管理: 更新当前企业的基本信息
    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {
        // 参数校验
        if (sysCompanyDTO == null){
            throw  new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        // 获取当前登录用户所属企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();
        // 更新企业信息
        SysCompany sysCompany = new SysCompany();
        sysCompany.setName(sysCompanyDTO.getName());
        sysCompany.setLogo(sysCompanyDTO.getLogo());
        sysCompany.setId(companyId);
        sysCompanayMapper.updateById(sysCompany);

        // 更新企业员工中的企业名称
        SysCompanyUser sysCompanyUser = new SysCompanyUser();
        sysCompanyUser.setCompanyName(sysCompanyDTO.getName());

        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        companayUserMapper.update(sysCompanyUser, wrapper);
    }

    @Override
    public void changeSysAdmin(String code, Long userId) {
        //参数校验
        if (StringUtils.isEmpty(code) || userId == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //根据用户id查询员工信息，得到手机号码
        SysCompanyUser sysCompanyUser = companayUserMapper.selectById(userId);

        //校验验证码是否正确
        String key = SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX + sysCompanyUser.getMobile();
        String redisCode = (String) redisTemplate.opsForValue().get(key);
        if(StringUtils.isEmpty(redisCode) || !redisCode.equals(code)){
            throw new NcException(ResponseEnum.INVALID_VERIFY_CODE);
        }

        // 先查询原本的主管理员id
        SysCompanyUserDTO currentAdmin = companyUserService.queryCurrentAdmin();


        // 查询系统管理员的角色id
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getCompanyId, currentAdmin.getCompanyId());
        wrapper.eq(SysRole::getRoleName, NcConstant.ADMIN_ROLE_SYS);
        SysRole sysRole = roleMapper.selectOne(wrapper);


        //更新员工角色关系表中的员工id
        LambdaQueryWrapper<SysCompanyUserRole> Wrapper = new LambdaQueryWrapper<>();
        Wrapper.eq(SysCompanyUserRole::getCompanyUserId, currentAdmin.getId());
        Wrapper.eq(SysCompanyUserRole::getRoleId, sysRole.getId());

        SysCompanyUserRole sysCompanyUserRole = new SysCompanyUserRole();
        sysCompanyUserRole.setCompanyUserId(userId);

        companyUserRoleMapper.update(sysCompanyUserRole, Wrapper);
    }
}
